home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 49 / Amiga Format CD49 (2000-01-17)(Future Publishing)(GB)(Track 1 of 3)[!][issue 2000-02].iso / +system+ / tools / sound / ahi / developer / devloper.lzx / examples / Low-level / PTdatatype / Class.c next >
C/C++ Source or Header  |  1979-08-22  |  7KB  |  280 lines

  1. /*
  2. **  Q&D Protracker DataType
  3. **
  4. **      Written by Martin Blom, based on the AIFF DataType by
  5. **  Olaf `Olsen' Barthel <olsen@sourcery.han.de>
  6. **  Public domain
  7. **
  8. */
  9.  
  10. extern void KPrintF(char *fmt,...);
  11. extern void __asm SlaveProcEntry(void);
  12.  
  13. #include "Data.h"
  14.  
  15. /* Our PlayerFunc() */
  16.  
  17. void __asm __saveds __interrupt PlayerFunc(
  18.     register __a0 struct Hook *me,
  19.     register __a2 struct AHIAudioCtrl *AudioCtrl,
  20.     register __a1 void *unused)
  21. {
  22.   struct ObjectData *ObjectData=me->h_Data;
  23.  
  24.   mt_music(&ObjectData->ptdata);
  25. }
  26.  
  27.  
  28.   /* ClassDispatch():
  29.    *
  30.    *  The class dispatcher routine.
  31.    */
  32.  
  33. Object * LIBENT
  34. ClassDispatch(REG(a0) Class *class,REG(a2) Object *object,REG(a1) Msg msg)
  35. {
  36.   struct  ClassBase *ClassBase = (struct ClassBase *) class->cl_UserData;
  37.   Object  *Result = NULL;
  38.   struct  ObjectData *ObjectData=NULL;
  39.   struct MsgPort *replyport;
  40.  
  41.   replyport = CreateMsgPort();
  42.  
  43.   if(replyport == NULL)
  44.   {
  45.     return NULL;
  46.   }
  47.  
  48.     // What message is it?
  49.  
  50.   switch(msg->MethodID)
  51.   {
  52.       // Create a new instance
  53.  
  54.     case OM_NEW:
  55.     {
  56.       BOOL success=FALSE;
  57.       BPTR File=NULL;
  58.  
  59.       if(Result = (Object *)DoSuperMethodA(class,object,msg))
  60.       {
  61.  
  62.         if(ObjectData = (struct ObjectData *) AllocVec(sizeof(struct ObjectData), MEMF_CLEAR))
  63.         {
  64.             // Fill in the remaining information
  65.  
  66.           SetDTAttrs(Result,NULL,NULL,
  67.             DTA_ObjName,    GetTagData(DTA_Name,NULL,((struct opSet *)msg)->ops_AttrList),
  68.             DTA_UserData,   ObjectData,
  69.             SDTA_Cycles,    1,
  70.             TAG_DONE);
  71.  
  72.           ObjectData->PlayerHook.h_Entry=(ULONG (*)()) PlayerFunc;
  73.           ObjectData->PlayerHook.h_Data=ObjectData;
  74.  
  75.           Forbid();
  76.           if(ObjectData->Slave = CreateNewProcTags(
  77.               NP_Entry,     &SlaveProcEntry,
  78.               NP_Name,      ClassBase->LibNode.lib_Node.ln_Name,
  79.               TAG_DONE))
  80.           {
  81.             ObjectData->Slave->pr_Task.tc_UserData = ClassBase;
  82.           }
  83.           Permit();
  84.  
  85.           if(ObjectData->Slave)
  86.           {
  87.             GetDTAttrs(Result,
  88.                 DTA_Handle,&File,
  89.                 TAG_DONE);
  90.             if(File)
  91.             {
  92.               LONG size;
  93.  
  94.               Seek(File, 0, OFFSET_END);
  95.               size = Seek(File, 0, OFFSET_BEGINNING);
  96.               if(ObjectData->ptdata.ptd_ModuleAddress=AllocVec(size, MEMF_PUBLIC))
  97.               {
  98.                 if(Read(File, ObjectData->ptdata.ptd_ModuleAddress, size) == size)
  99.                 {
  100.                     // Check if known module format
  101.                   if(*((ULONG *) ObjectData->ptdata.ptd_ModuleAddress+(1080/4)) == MKID)
  102.                   {
  103.                     ObjectData->Message.mn_ReplyPort = replyport;
  104.                     ObjectData->Command = COMMAND_INIT;
  105.                     PutMsg(&ObjectData->Slave->pr_MsgPort,
  106.                            (struct Message *) ObjectData);
  107.                     WaitPort(replyport);
  108.                     GetMsg(replyport);
  109.  
  110.                     if(ObjectData->Command != COMMAND_ERROR)
  111.                     {
  112.                       success=TRUE;
  113.                     }
  114.                   }
  115.                 }
  116.               }
  117.             }
  118.           }
  119.         }
  120.       }
  121.  
  122.       if(!success)
  123.       {
  124.         CoerceMethod(class,Result,OM_DISPOSE);
  125.         Result = NULL;
  126.       }
  127.       break;
  128.     }
  129.  
  130.  
  131.     case GM_GOACTIVE:
  132.     case DTM_TRIGGER:
  133.       {
  134.         GetDTAttrs(object,
  135.           DTA_UserData, &ObjectData,
  136.           TAG_DONE);
  137.         if(ObjectData)
  138.         {
  139.           ObjectData->Message.mn_ReplyPort = replyport;
  140.           ObjectData->Command = COMMAND_START;
  141.           PutMsg(&ObjectData->Slave->pr_MsgPort,
  142.                  (struct Message *) ObjectData);
  143.           WaitPort(replyport);
  144.           GetMsg(replyport);
  145.         }
  146.       }
  147.       Result = (Object *)DoSuperMethodA(class,object,msg);
  148.       break;
  149.  
  150.  
  151.  
  152.     case OM_DISPOSE:
  153.       GetDTAttrs(object,
  154.         DTA_UserData, &ObjectData,
  155.         TAG_DONE);
  156.       if(ObjectData)
  157.       {
  158.         SetDTAttrs(object,NULL,NULL,
  159.           DTA_UserData, NULL,
  160.           TAG_DONE);
  161.  
  162.         ObjectData->Message.mn_ReplyPort = replyport;
  163.         ObjectData->Command = COMMAND_END;
  164.         PutMsg(&ObjectData->Slave->pr_MsgPort,
  165.                (struct Message *) ObjectData);
  166.         WaitPort(replyport);
  167.         GetMsg(replyport);
  168.  
  169.         ObjectData->Command = COMMAND_QUIT;
  170.         PutMsg(&ObjectData->Slave->pr_MsgPort,
  171.                (struct Message *) ObjectData);
  172.         WaitPort(replyport);
  173.         GetMsg(replyport);
  174.  
  175.         FreeVec(ObjectData->ptdata.ptd_ModuleAddress);
  176.         FreeVec(ObjectData);
  177.       }
  178.       Result = (Object *)DoSuperMethodA(class,object,msg);
  179.       break;
  180.  
  181.       // Let the superclass handle the rest
  182.  
  183.     default:
  184.  
  185.       Result = (Object *)DoSuperMethodA(class,object,msg);
  186.  
  187.       break;
  188.   }
  189.  
  190.   DeleteMsgPort(replyport);
  191.   return(Result);
  192. }
  193.  
  194.  
  195. void LIBENT
  196. SlaveEntry(REG(a6) struct ClassBase *ClassBase)
  197. {
  198.   struct Process    *proc;
  199.   BOOL quit = FALSE;
  200.  
  201.   proc = (struct Process *)FindTask(NULL);
  202.  
  203.   while(! quit)
  204.   {
  205.     struct ObjectData *ObjectData;
  206.  
  207.     WaitPort(&proc->pr_MsgPort);
  208.     ObjectData = (struct ObjectData *) GetMsg(&proc->pr_MsgPort);
  209.  
  210.     switch(ObjectData->Command)
  211.     {
  212.       case COMMAND_INIT:
  213.       {
  214.         char prefs[40]="0 0";
  215.         int offset;
  216.         LONG audiomode, freq;
  217.  
  218.         ObjectData->ptdata.ptd_AHIBase = AHIBase;
  219.  
  220.           // Get desired audio mode and frequency
  221.  
  222.         GetVar( "ENV:DataTypes/Protracker", prefs, sizeof prefs, NULL );
  223.         offset=StrToLong(prefs,&audiomode);
  224.         if(offset  != -1)
  225.         {
  226.           if(StrToLong(&prefs[offset],&freq) != -1)
  227.           {
  228.             if(ObjectData->ptdata.ptd_AudioCtrl=AHI_AllocAudio(
  229.                 AHIA_AudioID,audiomode,
  230.                 AHIA_MixFreq,freq,
  231.                 AHIA_Channels,4,
  232.                 AHIA_Sounds,1,
  233.                 AHIA_PlayerFunc,&ObjectData->PlayerHook,
  234.                 AHIA_PlayerFreq,50<<16,
  235.                 AHIA_MinPlayerFreq,(32*2/5)<<16,
  236.                 AHIA_MaxPlayerFreq,(255*2/5)<<16,
  237.                 TAG_DONE))
  238.             {
  239.               if(mt_init(&ObjectData->ptdata))
  240.               {
  241.                 ObjectData->ModInitialized=TRUE;
  242.               }
  243.             }
  244.           }
  245.         }
  246.         if(! ObjectData->ModInitialized)
  247.         {
  248.           ObjectData->Command = COMMAND_ERROR;
  249.         }
  250.         ReplyMsg((struct Message *) ObjectData);
  251.         break;
  252.       }
  253.  
  254.       case COMMAND_START:
  255.         ReplyMsg((struct Message *) ObjectData);    // Don't block!
  256.         if(ObjectData->ModInitialized)
  257.         {
  258.           mt_start(&ObjectData->ptdata);
  259.  
  260.         }
  261.         break;
  262.  
  263.       case COMMAND_END:
  264.         ReplyMsg((struct Message *) ObjectData);    // Don't block!
  265.         if(ObjectData->ModInitialized)
  266.         {
  267.           mt_end(&ObjectData->ptdata);
  268.         }
  269.         break;
  270.  
  271.       case COMMAND_QUIT:
  272.         AHI_FreeAudio(ObjectData->ptdata.ptd_AudioCtrl);
  273.         ObjectData->Slave = NULL;
  274.         quit = TRUE;
  275.         ReplyMsg((struct Message *) ObjectData);
  276.         break;
  277.     }
  278.   }
  279. }
  280.